class Socket {
    wsUrl;
    // 消息处理回调
    messageHandlers = [];

    constructor(wsUrl) {
        this.wsUrl = wsUrl;
        // 初始化心跳配置
        this.heartBeat = {
            time: 30000, // 30秒心跳间隔
            reconnect: 5000 // 5秒重连间隔
        };
    }
    
    ModeCode = {
        MSG: "message",
        HEART_BEAT: 'heart_beat',
    }
    
    ws = null //websocket实例
    websocketState = false //websocket连接状态

    // 重连计数和最大重连次数
    reconnectCount = 0;
    maxReconnectAttempts = 5;

    heartBeat = {
        time: 30000, // 30秒心跳间隔
        reconnect: 5000 // 5秒重连间隔
    }

    reconnectTimer = null //重连定时器
    heartBeatTimer = null //心跳定时器
    waitingTimer = null //等待定时器
    connectionId = null //连接id

    /**
     * 注册消息处理回调函数
     * @param {Function} callback - 消息处理回调函数
     */
    onMessage(callback) {
        if (typeof callback === 'function') {
            this.messageHandlers.push(callback);
        } else {
            console.error('onMessage callback must be a function');
        }
    }

    /**
     * 建立WebSocket连接
     */
    connectWebSocket() {
        try {
            // 如果已有连接，先关闭
            if (this.ws) {
                this.ws.close();
                this.ws = null;
            }
            
            // 创建新的WebSocket连接
            this.ws = new WebSocket(this.wsUrl);
            
            // 生成连接ID用于日志标识
            this.connectionId = Math.random().toString(36).substr(2, 9);
            
            console.log('链接' + this.connectionId + '开始连接WebSocket:', this.wsUrl);
            
            // 初始化事件监听器
            this.init();
            
        } catch (error) {
            console.error('链接' + this.connectionId + 'WebSocket连接失败:', error);
            this.reconnectWebSocket();
        }
    }

    /**
     * 发送消息
     * @param {string} content - 要发送的消息内容
     */
    sendMessage(content) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            try {
                const message = {
                    ModeCode: this.ModeCode.MSG,
                    content: content,
                    timestamp: new Date().getTime()
                };
                
                this.ws.send(JSON.stringify(message));
                console.log('链接' + this.connectionId + '发送消息:', content);
                
            } catch (error) {
                console.error('链接' + this.connectionId + '发送消息失败:', error);
            }
        } else {
            console.warn('链接' + this.connectionId + 'WebSocket未连接，无法发送消息');
        }
    }

    /**
     * 初始化WebSocket事件监听器
     */
    init() {
        // 连接打开事件
        this.ws.addEventListener('open', (event) => {
            console.log('链接' + this.connectionId + 'WebSocket连接已建立');
            this.websocketState = true;
            this.reconnectCount = 0;
            
            // 启动心跳检测
            if (this.heartBeat && this.heartBeat.time) {
                this.startHeartbeat(this.heartBeat.time);
            }
        });
        
        // 接收消息事件
        this.ws.addEventListener('message', (event) => {
            console.log('链接' + this.connectionId + '收到消息', event.data);
            try {
                const data = JSON.parse(event.data);
                
                // 处理心跳响应
                if (data.ModeCode === this.ModeCode.HEART_BEAT) {
                    this.websocketState = true;
                    console.log('链接' + this.connectionId + '收到心跳响应');
                    return;
                }
                
                // 调用所有注册的消息处理回调
                this.messageHandlers.forEach(handler => {
                    try {
                        handler(data);
                    } catch (err) {
                        console.error('链接' + this.connectionId + '消息处理回调执行错误:', err);
                    }
                });
                
            } catch (err) {
                console.error('链接' + this.connectionId + '解析消息错误:', err);
                // 即使解析失败，也认为连接正常
                this.websocketState = true;
            }
        });

        // 连接关闭事件
        this.ws.addEventListener('close', (event) => {
            console.log('链接' + this.connectionId + 'WebSocket连接已关闭, code:', event.code, 'reason:', event.reason);
            this.websocketState = false;
            
            // 清除心跳定时器
            if (this.heartBeatTimer) {
                clearTimeout(this.heartBeatTimer);
                this.heartBeatTimer = null;
            }
            
            // 尝试重连
            this.reconnectWebSocket();
        });
        
        // 连接错误事件
        this.ws.addEventListener('error', (event) => {
            console.error('链接' + this.connectionId + 'WebSocket连接错误:', event);
            this.websocketState = false;
            
            // 尝试重连
            this.reconnectWebSocket();
        });
    }

    /**
     * 清除所有消息处理回调
     */
    clearMessageHandlers() {
        this.messageHandlers = [];
    }
    
    /**
     * 启动心跳检测
     * @param {number} time - 心跳间隔时间（毫秒）
     */
    startHeartbeat(time) {
        // 清除之前的定时器
        if (this.heartBeatTimer) {
            clearTimeout(this.heartBeatTimer);
        }
        
        this.heartBeatTimer = setTimeout(() => {
            if (this.ws && this.ws.readyState === WebSocket.OPEN) {
                // 发送心跳包
                this.ws.send(
                    JSON.stringify({
                        ModeCode: this.ModeCode.HEART_BEAT,
                        msg: new Date().getTime()
                    })
                );
                console.log('链接' + this.connectionId + '发送心跳包');
                
                // 等待服务器响应
                this.waitingServer();
            }
        }, time);
    }
    
    /**
     * 延时等待服务器响应 通过websocketState判断连线是否成功
     */
    waitingServer() {
        this.websocketState = false;
        
        // 清除之前的定时器
        if (this.waitingTimer) {
            clearTimeout(this.waitingTimer);
        }
        
        this.waitingTimer = setTimeout(() => {
            if (this.websocketState) {
                // 收到心跳响应，继续下一轮心跳
                this.startHeartbeat(this.heartBeat.time);
                return;
            }
            
            console.log('链接' + this.connectionId + '未收到心跳响应，尝试重连');
            this.closeAndReconnect();
        }, this.heartBeat.time);
    }
    
    /**
     * 重连WebSocket
     */
    reconnectWebSocket() {
        // 检查是否超过最大重连次数
        if (this.reconnectCount >= this.maxReconnectAttempts) {
            console.log('链接' + this.connectionId + '已超过最大重连次数' + this.maxReconnectAttempts + '，停止重连');
            return;
        }
        
        // 清除之前的定时器
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
        }

        this.reconnectTimer = setTimeout(() => {
            console.log('链接' + this.connectionId + '正在尝试重新连接' + (this.reconnectCount + 1) + '/' + this.maxReconnectAttempts);
            
            // 增加重连计数
            this.reconnectCount++;
            
            // 确保之前的链接已经关闭
            if (this.ws) {
                this.ws.close();
                this.ws = null;
            }
            
            // 创建新链接
            this.connectWebSocket();

        }, this.heartBeat.reconnect);
    }
    
    /**
     * 关闭连接并重连
     */
    closeAndReconnect() {
        if (this.ws) {
            this.ws.close();
        }
        this.reconnectWebSocket();
    }
    
    /**
     * 销毁Socket实例，清理所有资源
     */
    destroy() {
        console.log('链接' + this.connectionId + '销毁Socket实例');
        
        // 关闭WebSocket连接
        if (this.ws) {
            this.ws.close();
            this.ws = null;
        }
        
        // 清除所有回调
        this.clearMessageHandlers();
        
        // 清除所有定时器
        if (this.heartBeatTimer) {
            clearTimeout(this.heartBeatTimer);
            this.heartBeatTimer = null;
        }
        
        if (this.waitingTimer) {
            clearTimeout(this.waitingTimer);
            this.waitingTimer = null;
        }
        
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
            this.reconnectTimer = null;
        }
        
        // 重置状态
        this.websocketState = false;
        this.reconnectCount = 0;
        this.connectionId = null;
    }
    
    /**
     * 获取当前连接状态
     * @returns {boolean} 连接状态
     */
    isConnected() {
        return this.ws && this.ws.readyState === WebSocket.OPEN;
    }
    
    /**
     * 获取WebSocket连接状态
     * @returns {number} WebSocket.readyState
     */
    getReadyState() {
        return this.ws ? this.ws.readyState : WebSocket.CLOSED;
    }
}

export default Socket;